package simpleGeom;

import java.util.ArrayList;
import java.util.Random;

import processing.core.PGraphics;



public class Tree {
	ArrayList<Line3D>alllines;
	ArrayList<Line3D>lastLines;
	ArrayList<Face3D>faces;
	public float dynamic1=0.5f;
	public float dynamic2=0.2f;
	public float growFac=0.8f;
	public float treeSize=0.14f;
	Random random;
	
	public void init(float x,float y,float z,float h,int n){
		init(new Line3D(x,y,z,x,y,z+h),n);
		
	}
	public void init(Line3D line,int n){
		init(line,n,0);
	}
	
	
public void init(Line3D line,int n,int seed){
	random=new Random(seed);
	lastLines = new ArrayList<Line3D>();
	alllines = new ArrayList<Line3D>();
	alllines.add(line);
	lastLines.add(line);
	
	for (int j = 0; j < n; j++) {
		ArrayList<Line3D> newLines = new ArrayList<Line3D>();
		for (int i = 0; i < lastLines.size(); i++) {
			Line3D l = lastLines.get(i);
			Vec3D vec = l.getVector();
			float length = vec.mag();
			vec.mult(growFac);
			Vec3D midP = Vec3D.add(l.getP1(), vec);

			Vec3D u = vec.getOrthoVector();
			Vec3D v = vec.cross(u);
			v.normalize();

			Vec2D pUV = Vec2D.getPolar(random.nextFloat()*6.28f, length * dynamic2);
			Vec3D newV1 = Vec3D.mult(u, pUV.getX());
			Vec3D newV2 = Vec3D.mult(v, pUV.getY());
			Vec3D newP = Vec3D.add(newV1, newV2);
			newP.add(l.getP2());
			newP.add(vec);

			pUV = Vec2D.getPolar(random.nextFloat()*6.28f, length * dynamic1);
			newV1 = Vec3D.mult(u, pUV.getX());
			newV2 = Vec3D.mult(v, pUV.getY());
			Vec3D newP2 = Vec3D.add(newV1, newV2);
			newP2.add(l.getP2());
			vec.mult(0.7f);
			newP2.add(vec);

			Line3D l1 = new Line3D(l.getP2(), newP2);
			Line3D l2 = new Line3D(l.getP2(), newP);
			newLines.add(l1);
			newLines.add(l2);
			alllines.add(l1);
			alllines.add(l2);
		}
		lastLines = newLines;
	}
}


public void display(PGraphics g){
	g.beginShape(PGraphics.QUADS);
	for (int i = 0; i < alllines.size(); i++) {
		Line3D l = alllines.get(i);
		float d=l.getVector().mag();
		d*=treeSize;
		Vec2D v=Vec2D.getPolar(random.nextFloat()*6.3f, d);
		//g.line(l.getX1(), l.getY1(), l.getZ1(), l.getX2(), l.getY2(),l.getZ2());
		g.vertex(l.getX1()-d, l.getY1(), l.getZ1());
		g.vertex(l.getX2()-d, l.getY2(),l.getZ2());
		g.vertex(l.getX2()+d, l.getY2(),l.getZ2());
		g.vertex(l.getX1()+d, l.getY1(), l.getZ1());
		
		g.vertex(l.getX1(), l.getY1()-d, l.getZ1());
		g.vertex(l.getX2(), l.getY2()-d,l.getZ2());
		g.vertex(l.getX2(), l.getY2()+d,l.getZ2());
		g.vertex(l.getX1(), l.getY1()+d, l.getZ1());
		
		
	}
	g.endShape();
}

public void displayLeaves(PGraphics g,float size,int amount){
	
	
	g.beginShape(PGraphics.TRIANGLES);
	for (int i=0;i<lastLines.size();i++){
		Line3D l=lastLines.get(i);
		//System.out.println("lastLiens: "+l.getX2()+"  "+l.getY2()+"  "+l.getZ2());
		float x2=l.getX2();
		float y2=l.getY2();
		float z2=l.getZ2();
		g.vertex(x2,y2,z2);
		float rx1=random.nextFloat()*size-size*0.5f+x2;
		float ry1=random.nextFloat()*size-size*0.5f+y2;
		float rz1=random.nextFloat()*size-size*0.5f+z2;
		//System.out.println("lastLiens: "+rx1+"  "+ry1+"  "+rz1);
		g.vertex(rx1,ry1,rz1);
		float rx2=random.nextFloat()*size-size*0.5f+x2;
		float ry2=random.nextFloat()*size-size*0.5f+y2;
		float rz2=random.nextFloat()*size-size*0.5f+z2;
		g.vertex(rx2,ry2,rz2);
	}
	g.endShape();
}
}
